package com.tyylab.kestrel.framework.spring.rpc.feign.impl;

import com.alibaba.fastjson.JSONObject;
import com.tyylab.kestrel.framework.core.build.ProxyMethodNameGenerator;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.This;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * Feign Fallback Interceptor for handling exceptions and logging errors
 * @author tyylab
 */
@Slf4j
public class FeignFallbackInterceptor {
    
    @RuntimeType
    public static Object intercept(@Origin Method method, @This Object feignImpl, @AllArguments Object[] arguments) {
        String methodName = method.getName();
        String className = method.getDeclaringClass().getSimpleName();
        
        // Log the error details
        log.error("Feign call failed for method: {}.{} with arguments: {}", 
                className, methodName, Arrays.toString(arguments));
        
        // Return default value based on return type
        return getDefaultValue(method.getReturnType());
    }
    
    /**
     * Get default value for different return types
     * @param returnType the return type of the method
     * @return default value
     */
    private static Object getDefaultValue(Class<?> returnType) {
        if (returnType == void.class || returnType == Void.class) {
            return null;
        } else if (returnType == boolean.class || returnType == Boolean.class) {
            return false;
        } else if (returnType == char.class || returnType == Character.class) {
            return '\0';
        } else if (returnType == byte.class || returnType == Byte.class) {
            return (byte) 0;
        } else if (returnType == short.class || returnType == Short.class) {
            return (short) 0;
        } else if (returnType == int.class || returnType == Integer.class) {
            return 0;
        } else if (returnType == long.class || returnType == Long.class) {
            return 0L;
        } else if (returnType == float.class || returnType == Float.class) {
            return 0.0f;
        } else if (returnType == double.class || returnType == Double.class) {
            return 0.0;
        } else if (returnType == String.class) {
            return "";
        } else if (returnType.isArray()) {
            return java.lang.reflect.Array.newInstance(returnType.getComponentType(), 0);
        } else {
            // For complex objects, return null
            return null;
        }
    }
} 